package com.hsw.habit.frame.init;

import com.alibaba.fastjson.JSON;
import com.hsw.habit.common.CommonConstants;
import com.hsw.habit.common.CurrentUserConstants;
import com.hsw.habit.frame.annotation.NoLoginRequired;
import com.hsw.habit.frame.utils.MD5Util;
import com.hsw.habit.frame.utils.TextUtils;
import com.hsw.habit.frame.utils.TokenUtils;
import com.hsw.habit.model.JsonData;
import com.hsw.habit.model.User;
import com.hsw.habit.service.UserService;
import io.jsonwebtoken.Claims;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.logging.Logger;

public class AuthenticationInterceptor implements HandlerInterceptor {
    @Resource
    UserService userService;

    Logger logger = Logger.getLogger("task_item");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        NoLoginRequired methodAnnotation = method.getAnnotation(NoLoginRequired.class);

        String _debug = request.getParameter("_debug");
        String _sign = request.getParameter("_sign");
        String _token = request.getParameter("_token");
        String _timeStamp = request.getParameter("_time");
        String _app = request.getParameter("_app");

        String debug = TextUtils.isEmpty(_debug) ? "0" : _debug;
        String sign = TextUtils.isEmpty(_sign) ? "" : _sign;
        String token = TextUtils.isEmpty(_token) ? "" : _token;
        String time = TextUtils.isEmpty(_timeStamp) ? "" : _timeStamp;
        String app = TextUtils.isEmpty(_app) ? "" : _app;
        if (!TextUtils.isEmpty(debug) && debug.equals("1")) {
            if (!TextUtils.isEmpty(sign) && sign.equals("1")) {
                User user = new User();
                user.setId(1);
                request.setAttribute(CurrentUserConstants.CURRENT_USER, user);
            }
            return true;
        }

        Map<String, String[]> params = request.getParameterMap();

        if (null != params) {
            StringBuilder sb = new StringBuilder();
            params.forEach((s, strings) -> {
                if (!s.equals("_sign")) {
                    sb.append(strings[0]);
                }
            });
            String formatSign = MD5Util.md5(app + time + CommonConstants.APP_SECRET + MD5Util.md5(sb.toString()));
            if (!sign.equals(formatSign)) {
                returnJson(response, JSON.toJSONString(JsonData.error(4005, "非法请求")));
                return true;
            }
        }
        if (null == methodAnnotation) {
            if (token.isEmpty()) {
                returnJson(response, JSON.toJSONString(JsonData.error(1002, "没有token")));
                return true;
            }
            Claims claims = TokenUtils.parseJWT(token);
            String phone = claims.getId();
            User user = userService.findUserByPhone(phone);
            if (null == user) {
                returnJson(response, JSON.toJSONString(JsonData.error(1002, "")));
            } else {
                request.setAttribute(CurrentUserConstants.CURRENT_USER, user);
                request.setAttribute(CurrentUserConstants.CURRENT_USER_ID, user.getId());
            }
        }
        return true;
    }

    private void returnJson(HttpServletResponse response, String json) throws Exception {
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(json);
        } catch (IOException e) {

        } finally {
            if (writer != null)
                writer.close();
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
